/****************************************************************
 *                                                              *
 *  curvyCorners for MooTools                                   *
 *  -------------------------                                   *
 *                                                              *
 *  This script generates rounded corners for your divs.        *
 *                                                              *
 *  Version 1.2.9                                               *
 *  By: Mark Conway                                             *
 *  Hacked from Code By: Cameron Cooke and Tim Hutchison        *
 *                          of curvyCorners                     *
 *                                                              *
 *  Thank you curvyCorners                                      *
 *                                                              *
 *  Website:                                                    *
 *  Email:                                                      *
 *  Forum:                                                      *
 *                                                              *
 *                                                              *
 *  This library is free software; you can redistribute         *
 *  it and/or modify it under the terms of the GNU              *
 *  Lesser General Public License as published by the           *
 *  Free Software Foundation; either version 2.1 of the         *
 *  License, or (at your option) any later version.             *
 *                                                              *
 *  This library is distributed in the hope that it will        *
 *  be useful, but WITHOUT ANY WARRANTY; without even the       *
 *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
 *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
 *  License for more details.                                   *
 *                                                              *
 *  You should have received a copy of the GNU Lesser           *
 *  General Public License along with this library;             *
 *  Inc., 59 Temple Place, Suite 330, Boston,                   *
 *  MA 02111-1307 USA                                           *
 *                                                              *
 ****************************************************************/

/* MooTools Requirements
	Native
		Array
		String
	Element
		Element.Selectors
	Effects
		Fx.Style
		Fx.Styles
		Fx.Elements
	Plugins
		Color
*/

/*
	Usage:

	newCornersObj = new curvyCorners(settingsObj, "classNameStr");
	newCornersObj = new curvyCorners(settingsObj, divObj1[, divObj2[, divObj3[, . . . [, divObjN]]]]);
*/
function curvyCorners() {
	// Check parameters
	if(typeof(arguments[0]) != "object") throw newCurvyError("First parameter of curvyCorners() must be an object.");
	if(typeof(arguments[1]) != "object" && typeof(arguments[1]) != "string") throw newCurvyError("Second parameter of curvyCorners() must be an object or a class name.");

	// Get object(s)
	if(typeof(arguments[1]) == "string") {
		// Get elements by class name
		var startIndex = 0;
		var boxCol = $$("."+arguments[1]);
	} else {
		// Get objects
		var startIndex = 1;
		var boxCol = arguments;
	}

	// Create return collection/object
	var curvyCornersCol = new Array();

	// Create array of html elements that can have rounded corners
	if(arguments[0].validTags)
		var validElements = arguments[0].validTags;
	else
		var validElements = ["div"]; // Default

	// Loop through each argument
	for(var i = startIndex, j = boxCol.length; i < j; i++) {
		// Current element tag name
		var currentTag = boxCol[i].tagName.toLowerCase();

		if(validElements.indexOf[currentTag] !== -1)
			curvyCornersCol[curvyCornersCol.length] = new curvyObject(arguments[0], boxCol[i]);
	}

	this.objects = curvyCornersCol;

	// Applys the curvyCorners to all objects
	this.applyCornersToAll = function() {
		for(var x = 0, k = this.objects.length; x < k; x++)
			this.objects[x].applyCorners();
	};
}

// curvyCorners object (can be called directly)
function curvyObject() {
	// Setup Globals
	this.box              = arguments[1];
	this.settings         = arguments[0];
	this.topContainer     = null;
	this.bottomContainer  = null;
	this.masterCorners    = new Array();

	// Set formatting propertes
	this.boxHeight       = this.box.getStyle("height").toInt();
	this.boxWidth        = this.box.getStyle("width").toInt();
	this.borderWidth     = this.box.getStyle("border-top-width").toInt();
	this.boxColor        = this.box.getStyle("background-color");
	this.boxPadding      = this.box.getStyle("padding-top").toInt();
	this.borderColor     = this.box.getStyle("border-top-color");
	this.borderString    = this.borderWidth + "px" + " solid " + this.borderColor;
	this.backgroundImage = this.box.getStyle("background-image");

	// Make box relative if not already absolute and remove any padding
	if(this.box.getStyle("position") != "absolute") this.box.setStyle('position', 'relative');
	this.box.setStyle('padding', 0);
//	this.box.setStyle('width', this.boxWidth - 20 ); // Doesn't work, won't resize with resizing of window

	// Opera includes padding in height and width, skews a few things below, and since we have now removed the padding...
	if(window.opera) {
		this.boxHeight     = this.box.getStyle("height").toInt();
		this.boxWidth      = this.box.getStyle("width").toInt();
	}

	// If IE and height and width are not set, we need to set width so that we get positioning
//	if(window.ie && this.boxWidth == "auto" && this.boxHeight == "auto") this.box.setStyle('width', '100%');

	// Resize box so that it stays to the orignal height

	/*
		AutoPad! apply padding if set.
	*/
	if(this.settings.autoPad === true && this.boxPadding > 0) {
		var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0);
		var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0);

		/*
			Very backwards way of doing this.  This is to avoid a problem where other javascript was
			losing functionality that was in this.box that was enabled before curvyCorners runs.  What we
			are doing here now is cloning this.box to get all of the properties, emptying the clone,
			removing all properties from this.box, adding the new styles to the 
		*/
		this.box = this.box.clone().empty().injectBefore(this.box).adopt(this.box);
		var properties = ["style", "class", "name", "id"];
		for ( var i = 0; i < properties.length; i++ )
			this.box.getFirst().removeProperty( properties[i] );
		this.box.getFirst().setStyles({
			'padding-left': this.boxPadding,
			'padding-right': this.boxPadding
		});

		// Apply top padding
		if(topMaxRadius < this.boxPadding)
			this.box.getFirst().setStyle('padding-top', (topMaxRadius - this.boxPadding));
	
		// Apply Bottom padding
		if(botMaxRadius < this.boxPadding)
			this.box.getFirst().setStyle('padding-bottom', (botMaxRadius - this.boxPadding));
	}

	/*
		This method creates the corners and
		applies them to the div element.
	*/
	this.applyCorners = function() {
		/*
			Create top and bottom containers.
			These will be used as a parent for the corners and bars.
		*/
		// Only build top bar if a top corner is to be draw
		if(this.settings.tl || this.settings.tr) {
			var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0);
			var topMainContainer = new Element('div', {
				'styles': {
					'width': '100%',
					'fontSize': '1px',
					'overflow': 'hidden',
					'position': 'absolute',
					'paddingLeft': this.borderWidth,
					'paddingRight': this.borderWidth,
					'height': topMaxRadius,
					'top': -topMaxRadius,
					'left': -this.borderWidth
				}
			});
			this.topContainer = topMainContainer.injectTop(this.box);
		}

		// Only build bottom bar if a bottom corner is to be draw
		if(this.settings.bl || this.settings.br) {
			var botMaxRadius = Math.max(this.settings.bl ? this.settings.bl.radius : 0, this.settings.br ? this.settings.br.radius : 0);
			var botMainContainer = new Element('div', {
				'styles': {
					'width': '100%',
					'fontSize': '1px',
					'overflow': 'hidden',
					'position': 'absolute',
					'paddingLeft': this.borderWidth,
					'paddingRight': this.borderWidth,
					'height': botMaxRadius,
					'bottom': -botMaxRadius,
					'left': -this.borderWidth
				}
			});
			this.bottomContainer = botMainContainer.injectInside(this.box);
		}

		// Turn off current borders
		if(this.topContainer) this.box.style.borderTopWidth = "0px";
		if(this.bottomContainer) this.box.style.borderBottomWidth = "0px";

		// Create array of available corners
		var corners = ["tr", "tl", "br", "bl"];

		/*
			Loop for each corner
		*/
		for(var i in corners) {
			// Get current corner type from array
			var cc = corners[i];

			// Has the user requested the currentCorner be round?
			if(!this.settings[cc]) {
				// No
				if(((cc == "tr" || cc == "tl") && this.topContainer != null) || ((cc == "br" || cc == "bl") && this.bottomContainer != null)) {
					// We need to create a filler div to fill the space upto the next horzontal corner.
					var newCorner = new Element('div', {
						'styles': {
							'position': 'relative',
							'fontSize': '1px',
							'overflow': 'hidden'
						}
					});

					// Add background image?
					if(this.backgroundImage == "none")
						newCorner.setStyle('background-color', this.boxColor);
					else
						newCorner.setStyle('background-image', this.backgroundImage);

					switch(cc) {
						case "tl":
							newCorner.setStyles({
								'height': topMaxRadius - this.borderWidth,
								'margin-right': this.settings.tr.radius - (this.borderWidth*2),
								'border-left': this.borderString,
								'border-top': this.borderString,
								'left': -this.borderWidth
							});
							break;

						case "tr":
							newCorner.setStyles({
								'height': topMaxRadius - this.borderWidth,
								'margin-left': this.settings.tl.radius - (this.borderWidth*2),
								'border-right': this.borderString,
								'border-top': this.borderString,
								'background-position': -(topMaxRadius + this.borderWidth) + "px 0px",
								'left': this.borderWidth
							});
							break;

						case "bl":
							newCorner.setStyles({
								'height': botMaxRadius - this.borderWidth,
								'margin-right': this.settings.br.radius - (this.borderWidth*2),
								'border-left': this.borderString,
								'border-bottom': this.borderString,
								'background-position': (-this.borderWidth) + "px " + (-this.boxHeight - botMaxRadius - this.borderWidth) + "px",
								'left': this.borderWidth
							});
							break;

						case "br":
							newCorner.setStyles({
								'height': botMaxRadius - this.borderWidth,
								'margin-left': this.settings.bl.radius - (this.borderWidth*2),
								'border-right': this.borderString,
								'border-bottom': this.borderString,
								'background-position': (-width + botMaxRadius + this.borderWidth) + "px " + (-this.boxHeight - botMaxRadius - this.borderWidth) + "px",
								'left': this.borderWidth
							});
							break;
					}
				}
			} else {
				/*
					PERFORMANCE NOTE:

					If more than one corner is requested and a corner has been already
					created for the same radius then that corner will be used as a master and cloned.
					The pixel bars will then be repositioned to form the new corner type.
					All new corners start as a bottom right corner.
				*/
				if(this.masterCorners[this.settings[cc].radius]) {
					// Create clone of the master corner
					var newCorner = this.masterCorners[this.settings[cc].radius].cloneNode(true);
				} else {
					// Yes, we need to create a new corner
					var newCorner = new Element('div', {
						'styles': {
							'height': this.settings[cc].radius,
							'width':  this.settings[cc].radius,
							'position': 'absolute',
							'overflow': 'visible'
						}
					});

					// THE FOLLOWING BLOCK OF CODE CREATES A ROUNDED CORNER
					// ---------------------------------------------------- TOP

					// Get border radius
					var borderRadius = this.settings[cc].radius - this.borderWidth;

					// Cycle the x-axis
					for(var intx = 0, j = this.settings[cc].radius; intx < j; intx++) {
						// Calculate the value of y1 which identifies the pixels inside the border
						if((intx +1) >= borderRadius)
							var y1 = -1;
						else
							var y1 = Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow((intx+1), 2))) - 1;

						// Only calculate y2 and y3 if there is a border defined
						if(borderRadius != j) {
							if(intx >= borderRadius)
								var y2 = -1;
							else
								var y2 = Math.ceil(Math.sqrt(Math.pow(borderRadius,2) - Math.pow(intx, 2)));

							if((intx+1) >= j)
								var y3 = -1;
							else
								var y3 = Math.floor(Math.sqrt(Math.pow(j ,2) - Math.pow((intx+1), 2))) - 1;
						}

						// Calculate y4
						if(intx >= j)
							var y4 = -1;
						else
							var y4 = Math.ceil(Math.sqrt(Math.pow(j ,2) - Math.pow(intx, 2)));

						// Draw bar on inside of the border with foreground color
						if(y1 > -1) this.drawPixel(intx, 0, this.boxColor, 1, (y1+1), newCorner, -1, this.settings[cc].radius);

						// Only draw border/foreground antialiased pixels and border if there is a border defined
						if(borderRadius != j) {
							// Cycle the y-axis
							for(var inty = (y1 + 1); inty < y2; inty++) {
								// Draw anti-alias pixels
								if(this.settings.antiAlias) {
									// For each of the pixels that need anti aliasing between the foreground and border color draw single pixel divs
									if(this.backgroundImage != "none") {
										var borderFract = pixelFraction(intx, inty, borderRadius);

										if(borderFract < .30)
											this.drawPixel(intx, inty, this.borderColor, 1, 1, newCorner, 0, this.settings[cc].radius);
										else
											this.drawPixel(intx, inty, this.borderColor, 1, 1, newCorner, -1, this.settings[cc].radius);
									} else {
										if ( this.boxColor == "transparent") {
											this.drawPixel(intx, inty, this.borderColor, 1-pixelFraction(intx, inty, borderRadius), 1, newCorner, 0, this.settings[cc].radius);
										} else {
											var pixelcolor = new Color(this.borderColor).mix(this.boxColor, pixelFraction(intx, inty, borderRadius)*100);
											this.drawPixel(intx, inty, pixelcolor, 1, 1, newCorner, 0, this.settings[cc].radius);
										}
									}
								}
							}

							// Draw bar for the border
							if(this.settings.antiAlias) {
								if(y3 >= y2) {
									if (y2 == -1) y2 = 0;
									this.drawPixel(intx, y2, this.borderColor, 1, (y3 - y2 + 1), newCorner, 0, 0);
								}
							} else {
								if(y3 >= y1)
									this.drawPixel(intx, (y1 + 1), this.borderColor, 1, (y3 - y1), newCorner, 0, 0);
							}

							// Set the color for the outside curve
							var outsideColor = this.borderColor;
						} else {
							// Set the color for the outside curve
							var outsideColor = this.boxColor;
							var y3 = y1;
						}

						// Draw aa pixels?
						if(this.settings.antiAlias) {
							// Cycle the y-axis and draw the anti aliased pixels on the outside of the curve
							for(var inty = (y3 + 1); inty < y4; inty++) {
								// For each of the pixels that need anti aliasing between the foreground/border color & background draw single pixel divs
								this.drawPixel(intx, inty, outsideColor, pixelFraction(intx, inty , j), 1, newCorner, ((this.borderWidth > 0)? 0 : -1), this.settings[cc].radius);
							}
						}
					}

					// END OF CORNER CREATION
					// ---------------------------------------------------- END

					// We now need to store the current corner in the masterConers array
					this.masterCorners[this.settings[cc].radius] = newCorner.cloneNode(true);
				}

				/*
					Now we have a new corner we need to reposition all the pixels unless
					the current corner is the bottom right.
				*/
				if(cc != "br") {
					// Loop through all children (pixel bars)
					for(var t = 0, k = newCorner.childNodes.length; t < k; t++) {
						// Get current pixel bar
						var pixelBar = newCorner.childNodes[t];

						// Get current top and left properties
						var pixelBarTop    = pixelBar.getStyle("top").toInt();
						var pixelBarLeft   = pixelBar.getStyle("left").toInt();
						var pixelBarHeight = pixelBar.getStyle("height").toInt();

						// Reposition pixels
						if(cc == "tl" || cc == "bl")
							pixelBar.setStyle('left', this.settings[cc].radius -pixelBarLeft -1); // Left
						if(cc == "tr" || cc == "tl")
							pixelBar.setStyle('top', this.settings[cc].radius -pixelBarHeight -pixelBarTop); // Top

						switch(cc) {
							case "tr":
								pixelBar.setStyle('background-position', -Math.abs((this.boxWidth - this.settings[cc].radius + this.borderWidth) + pixelBarLeft) + "px " + -Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px");
								break;

							case "tl":
								pixelBar.setStyle('background-position', -Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px " + -Math.abs(this.settings[cc].radius -pixelBarHeight -pixelBarTop - this.borderWidth) + "px");
								break;

							case "bl":
								pixelBar.setStyle('background-position', -Math.abs((this.settings[cc].radius -pixelBarLeft -1) - this.borderWidth) + "px " + -Math.abs((this.boxHeight + this.settings[cc].radius + pixelBarTop) -this.borderWidth) + "px");
								break;
						}
					}
				}
			}

			if(newCorner) {
				// Position the container
				switch(cc) {
					case "tl":
						if(newCorner.getStyle('position') == "absolute") {
							newCorner.setStyle('top', '0px');
							newCorner.setStyle('left', '0px');
						}
						if(this.topContainer) newCorner.injectInside(this.topContainer);
						break;

					case "tr":
						if(newCorner.getStyle('position') == "absolute") {
							newCorner.setStyle('top', '0px');
							newCorner.setStyle('right', '0px');
						}
						if(this.topContainer) newCorner.injectInside(this.topContainer);
						break;

					case "bl":
						if(newCorner.getStyle('position') == "absolute") {
							newCorner.setStyle('bottom', '0px');
							newCorner.setStyle('left', '0px');
						}
						if(this.bottomContainer) newCorner.injectInside(this.bottomContainer);
						break;

					case "br":
						if(newCorner.getStyle('position') == "absolute") {
							newCorner.setStyle('bottom', '0px');
							newCorner.setStyle('right', '0px');
						}
						if(this.bottomContainer) newCorner.injectInside(this.bottomContainer);
						break;
				}
			}
		}

		/*
			The last thing to do is draw the rest of the filler DIVs.
			We only need to create a filler DIVs when two corners have
			different radii in either the top or bottom container.
		*/

		// Find out which corner has the bigger radius and get the difference amount
		var radiusDiff = new Array();
		radiusDiff["t"] = Math.abs(this.settings.tl.radius - this.settings.tr.radius);
		radiusDiff["b"] = Math.abs(this.settings.bl.radius - this.settings.br.radius);

		for(var z in radiusDiff) {
			// FIX for prototype lib
			if(z == "t" || z == "b") {
				if(radiusDiff[z]) {
					// Get the type of corner that is the smaller one
					var smallerCornerType = ((this.settings[z + "l"].radius < this.settings[z + "r"].radius)? z +"l" : z +"r");

					// First we need to create a DIV for the space under the smaller corner
					var newFiller = new Element('div', {
						'styles': {
							'height': radiusDiff[z],
							'width':  this.settings[smallerCornerType].radius,
							'position': 'absolute',
							'overflow': 'hidden',
							'background-color': this.boxColor
						}
					});

					// Position filler
					switch(smallerCornerType) {
						case "tl":
							newFiller.setStyles({
								'bottom': '0px',
								'left': '0px',
								'border-left': this.borderString
							});
							newFiller.injectInside(this.topContainer);
							break;

						case "tr":
							newFiller.setStyles({
								'bottom': '0px',
								'right': '0px',
								'border-right': this.borderString
							});
							newFiller.injectInside(this.topContainer);
							break;

						case "bl":
							newFiller.setStyles({
								'top': '0px',
								'left': '0px',
								'border-left': this.borderString
							});
							newFiller.injectInside(this.bottomContainer);
							break;

						case "br":
							newFiller.setStyles({
								'top': '0px',
								'right': '0px',
								'border-right': this.borderString
							});
							newFiller.injectInside(this.bottomContainer);
							break;
					}
				}

				// Create the bar to fill the gap between each corner horizontally
				var newFillerBar = new Element('div', {
					'styles': {
						'position': 'relative',
						'overflow': 'hidden',
						'background-color': this.boxColor,
						'background-image': this.backgroundImage
					}
				});

				switch(z) {
					case "t":
						// Top Bar
						if(this.topContainer) {
							// Edit by Asger Hallas: Check if settings.xx.radius is not false
							if(this.settings.tl.radius && this.settings.tr.radius) {
								newFillerBar.setStyles({
									'height': topMaxRadius - this.borderWidth,
									'margin-left': this.settings.tl.radius - this.borderWidth,
									'margin-right': this.settings.tr.radius - this.borderWidth,
									'border-top': this.borderString
								});
//newFillerBar.setText("topbar");
								if(this.backgroundImage != "none")
									newFillerBar.setStyle('background-position', (-topMaxRadius - this.borderWidth) + "px 0px");

								newFillerBar.injectInside(this.topContainer);
							}

							// Reposition the boxes background image
							this.box.setStyle('background-position', "0px " + (-topMaxRadius + this.borderWidth) + "px");
						}
						break;

					case "b":
						if(this.bottomContainer) {
							// Edit by Asger Hallas: Check if settings.xx.radius is not false
							if(this.settings.bl.radius && this.settings.br.radius) {
								// Bottom Bar
								newFillerBar.setStyles({
									'height': botMaxRadius - this.borderWidth,
									'margin-left': this.settings.bl.radius - this.borderWidth,
									'margin-right': this.settings.br.radius - this.borderWidth,
									'border-bottom': this.borderString
								});
//newFillerBar.setText("bottombar");
								if(this.backgroundImage != "none")
									newFillerBar.setStyle('background-position', (-botMaxRadius - this.borderWidth) + "px " + (-this.boxHeight - topMaxRadius - this.borderWidth) + "px");

								newFillerBar.injectInside(this.bottomContainer);
							}
						}
						break;
				}
			}
		}
	};

	/*
		This function draws the pixels
	*/
	this.drawPixel = function(intx, inty, color, transAmount, height, newCorner, image, cornerRadius) {
		// Create pixel
		var pixel = new Element('div', {
			'styles': {
				'height': height,
				'width': '1px',
				'position': 'absolute',
				'overflow': 'hidden'
			}
		});

		// Max Top Radius
		var topMaxRadius = Math.max(this.settings.tl ? this.settings.tl.radius : 0, this.settings.tr ? this.settings.tr.radius : 0);

		// Dont apply background image to border pixels
		if(image == -1 && this.backgroundImage != "none") {
			pixel.setStyles({
				'background-image': this.backgroundImage,
				'background-position': (- this.boxWidth + cornerRadius - intx - this.borderWidth) + "px " + (- this.boxHeight - topMaxRadius - inty + this.borderWidth) + "px"
			});
		} else {
			pixel.setStyle('background-color', color);
		}

		// Set opacity if the transparency is anything other than 100
		if (transAmount != 1) {
			pixel.setOpacity(transAmount);
		}

		// Set the pixels position
		pixel.setStyles({
			'top': inty,
			'left': intx
		});

		pixel.injectInside(newCorner);
	};
}

// ------------- UTILITY FUNCTIONS

/*
	For a pixel cut by the line determines the fraction of the pixel on the 'inside' of the
	line.  Returns a number between 0 and 1
*/
function pixelFraction(x, y, r) {
	var pixelfraction = 0;

	/*
		determine the co-ordinates of the two points on the perimeter of the pixel that the
		circle crosses
	*/
	var xvalues = [];
	var yvalues = [];
	var whatsides = "";

	// x + 0 = Left
	var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x,2)));

	if ((intersect >= y) && (intersect < (y+1))) {
		whatsides += "Left";
		xvalues.extend([0]);
		yvalues.extend([intersect - y]);
	}
	// y + 1 = Top
	var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y+1,2)));

	if ((intersect >= x) && (intersect < (x+1))) {
		whatsides += "Top";
		xvalues.extend([intersect - x]);
		yvalues.extend([1]);
	}
	// x + 1 = Right
	var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(x+1,2)));

	if ((intersect >= y) && (intersect < (y+1))) {
		whatsides += "Right";
		xvalues.extend([1]);
		yvalues.extend([intersect - y]);
	}
	// y + 0 = Bottom
	var intersect = Math.sqrt((Math.pow(r,2) - Math.pow(y,2)));

	if ((intersect >= x) && (intersect < (x+1))) {
		whatsides += "Bottom";
		xvalues.extend([intersect - x]);
		yvalues.extend([0]);
	}

	/*
		depending on which sides of the perimeter of the pixel the circle crosses calculate the
		fraction of the pixel inside the circle
	*/
	switch (whatsides) {
		case "LeftRight":
			pixelfraction = Math.min(yvalues[0],yvalues[1]) + Math.abs(yvalues[0] - yvalues[1])/2;
			break;

		case "TopRight":
			pixelfraction = 1-(((1-xvalues[0])*(1-yvalues[1]))/2);
			break;

		case "TopBottom":
			pixelfraction = Math.min(xvalues[0],xvalues[1]) + Math.abs(xvalues[0] - xvalues[1])/2;
			break;

		case "LeftBottom":
			pixelfraction = (yvalues[0]*xvalues[1])/2;
			break;

		default:
			pixelfraction = 1;
	}

	return pixelfraction;
}

// Displays error message
function newCurvyError(errorMessage) {
	return new Error("curvyCorners Error:\n" + errorMessage);
}